package com.umeox.watch.moto.agora;

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.WindowManager;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.List;

import io.agora.rtc.mediaio.IVideoFrameConsumer;
import io.agora.rtc.mediaio.MediaIO;
import io.agora.rtc.mediaio.TextureSource;

/**
 * Created by Rambo 2020/7/1
 * Describe:
 */
public class UmeoxTextureCamera extends TextureSource {

    private static final String TAG = UmeoxTextureCamera.class.getSimpleName();
    private Context mContext;
    private Camera camera;
    private Camera.CameraInfo info;

    public UmeoxTextureCamera(Context context, int width, int height) {
        super(null, width, height);
        this.mContext = context;
    }

    @Override
    public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) {
        super.onTextureFrameAvailable(oesTextureId, transformMatrix, timestampNs);
        int rotation = this.getFrameOrientation();
        WeakReference<IVideoFrameConsumer> consumerWeakRef = this.mConsumer;
        if (consumerWeakRef != null) {
            IVideoFrameConsumer consumer = consumerWeakRef.get();
            if (consumer != null) {
                consumer.consumeTextureFrame(oesTextureId, MediaIO.PixelFormat.TEXTURE_OES.intValue(), this.mWidth, this.mHeight, rotation, System.currentTimeMillis(), transformMatrix);
            }
        }
    }

    @Override
    protected boolean onCapturerOpened() {
        try {
            this.openCamera();
            this.camera.setPreviewTexture(this.getSurfaceTexture());
            this.camera.startPreview();
            return true;
        } catch (IOException var2) {
            Log.e(TAG, "initialize: failed to initalize camera device");
            return false;
        }
    }

    @Override
    protected boolean onCapturerStarted() {
        this.camera.startPreview();
        return true;
    }

    @Override
    protected void onCapturerStopped() {
        this.camera.stopPreview();
    }

    @Override
    protected void onCapturerClosed() {
        this.releaseCamera();
    }


    private int getDeviceOrientation() {
        WindowManager wm = (WindowManager) this.mContext.getSystemService(Context.WINDOW_SERVICE);
        int orientation;
        switch (wm.getDefaultDisplay().getRotation()) {
            case 0:
            default:
                orientation = 0;
                break;
            case 1:
                orientation = 90;
                break;
            case 2:
                orientation = 180;
                break;
            case 3:
                orientation = 270;
        }

        return orientation;
    }

    private int getFrameOrientation() {
        int rotation = this.getDeviceOrientation();
        if (this.info.facing == 0) {
            rotation = 360 - rotation;
        }

        return (this.info.orientation + rotation) % 360;
    }

    private void openCamera() {
        if (this.camera != null) {
            throw new RuntimeException("camera already initialized");
        } else {


            this.info = new Camera.CameraInfo();
            int numCameras = Camera.getNumberOfCameras();

            for(int i = 0; i < numCameras; ++i) {
                Camera.getCameraInfo(i, this.info);
                if (this.info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    this.camera = Camera.open(i);
                    break;
                }
            }

            if (this.camera == null) {
                Log.d(TAG, "No front-facing camera found; opening default");
                this.camera = Camera.open();
            }

            if (this.camera == null) {
                throw new RuntimeException("Unable to open camera");
            } else {
                Camera.Parameters parms = this.camera.getParameters();
                List<int[]> frameRates = parms.getSupportedPreviewFpsRange();
                int minFps = frameRates.get(frameRates.size() - 1)[0];
                int maxFps = frameRates.get(frameRates.size() - 1)[1];

                parms.setPreviewFpsRange(minFps, maxFps);
                parms.setPreviewSize(this.mWidth, this.mHeight);
                parms.setRecordingHint(true);
                parms.setAutoExposureLock(false);
                parms.setExposureCompensation(6);

                this.camera.setParameters(parms);
                Camera.Size cameraPreviewSize = parms.getPreviewSize();
                String previewFacts = cameraPreviewSize.width + "x" + cameraPreviewSize.height;
                Log.i(TAG, "Camera config: " + previewFacts);
            }
        }
    }

    private void releaseCamera() {
        if (this.camera != null) {
            this.camera.stopPreview();

            try {
                this.camera.setPreviewTexture(null);
            } catch (Exception var2) {
                Log.e(TAG, "failed to set Preview Texture");
            }

            this.camera.release();
            this.camera = null;
            Log.d(TAG, "releaseCamera -- done");
        }

    }
}
